<!DOCTYPE html>
<html lang=zh>
<head>
    <meta charset="utf-8">
    
    <title>第五章：使用QueryDSL与SpringDataJPA实现查询返回自定义对象 | 恒宇少年De成长之路</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
    <meta name="description" content="在我们实际项目开发中，往往会遇到一种多表关联查询并且仅需要返回多表内的几个字段最后组合成一个集合或者实体。这种情况在传统的查询中我们无法控制查询的字段，只能全部查询出后再做出分离，这种也是我们最不愿意看到的处理方式，这种方式会产生繁琐、复杂、效率低、代码阅读性差等等问题。QueryDSL为我们提供了一个返回自定义对象的工具类型，而Java8新特性Collection中stream方法也能够完成返回">
<meta name="keywords" content="SpringBoot,QueryDSL">
<meta property="og:type" content="article">
<meta property="og:title" content="第五章：使用QueryDSL与SpringDataJPA实现查询返回自定义对象">
<meta property="og:url" content="http://blog.yuqiyu.com/querydsl-chapter-5/index.html">
<meta property="og:site_name" content="恒宇少年De成长之路">
<meta property="og:description" content="在我们实际项目开发中，往往会遇到一种多表关联查询并且仅需要返回多表内的几个字段最后组合成一个集合或者实体。这种情况在传统的查询中我们无法控制查询的字段，只能全部查询出后再做出分离，这种也是我们最不愿意看到的处理方式，这种方式会产生繁琐、复杂、效率低、代码阅读性差等等问题。QueryDSL为我们提供了一个返回自定义对象的工具类型，而Java8新特性Collection中stream方法也能够完成返回">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="http://upload-images.jianshu.io/upload_images/4461954-8c9862af270a9d02.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="http://upload-images.jianshu.io/upload_images/4461954-24a7bc6f80b6b210.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="http://upload-images.jianshu.io/upload_images/4461954-f1d4cb64234b160a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:updated_time" content="2018-01-23T16:12:54.305Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="第五章：使用QueryDSL与SpringDataJPA实现查询返回自定义对象">
<meta name="twitter:description" content="在我们实际项目开发中，往往会遇到一种多表关联查询并且仅需要返回多表内的几个字段最后组合成一个集合或者实体。这种情况在传统的查询中我们无法控制查询的字段，只能全部查询出后再做出分离，这种也是我们最不愿意看到的处理方式，这种方式会产生繁琐、复杂、效率低、代码阅读性差等等问题。QueryDSL为我们提供了一个返回自定义对象的工具类型，而Java8新特性Collection中stream方法也能够完成返回">
<meta name="twitter:image" content="http://upload-images.jianshu.io/upload_images/4461954-8c9862af270a9d02.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
    

    
        <link rel="alternate" href="/" title="恒宇少年De成长之路" type="application/atom+xml" />
    

    

    <link rel="stylesheet" href="/libs/font-awesome/css/font-awesome.min.css">
    <link rel="stylesheet" href="/libs/open-sans/styles.css">
    <link rel="stylesheet" href="/libs/source-code-pro/styles.css">

    <link rel="stylesheet" href="/css/style.css">

    <script src="/libs/jquery/2.1.3/jquery.min.js"></script>
    
    
        <link rel="stylesheet" href="/libs/lightgallery/css/lightgallery.min.css">
    
    
        <link rel="stylesheet" href="/libs/justified-gallery/justifiedGallery.min.css">
    
    
    
    


</head>

<body>
    <div id="container">
        <header id="header">
    <div id="header-main" class="header-inner">
        <div class="outer">
            <a href="/" id="logo">
                <i class="logo"></i>
                <span class="site-title">恒宇少年De成长之路</span>
            </a>
            <nav id="main-nav">
                
                    <a class="main-nav-link" href="/.">首页</a>
                
                    <a class="main-nav-link" href="/archives">时间轴</a>
                
                    <a class="main-nav-link" href="/categories">文章专题</a>
                
                    <a class="main-nav-link" href="/tags">标签云</a>
                
                    <a class="main-nav-link" href="/about">关于我</a>
                
            </nav>
            
                
                <nav id="sub-nav">
                    <div class="profile" id="profile-nav">
                        <a id="profile-anchor" href="javascript:;">
                            <img class="avatar" src="/css/images/avatar.png" />
                            <i class="fa fa-caret-down"></i>
                        </a>
                    </div>
                </nav>
            
            <div id="search-form-wrap">

    <form class="search-form">
        <input type="text" class="ins-search-input search-form-input" placeholder="搜索" />
        <!--button type="submit" class="search-form-submit"></button-->
    </form>
    <div class="ins-search">
    <div class="ins-search-mask"></div>
    <div class="ins-search-container">
        <div class="ins-input-wrapper">
            <input type="text" class="ins-search-input" placeholder="想要查找什么..." />
            <span class="ins-close ins-selectable"><i class="fa fa-times-circle"></i></span>
        </div>
        <div class="ins-section-wrapper">
            <div class="ins-section-container"></div>
        </div>
    </div>
</div>
<script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: '文章',
            PAGES: '页面',
            CATEGORIES: '分类',
            TAGS: '标签',
            UNTITLED: '(未命名)',
        },
        ROOT_URL: '/',
        CONTENT_URL: '/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>
<script src="/js/insight.js"></script>

</div>
        </div>
    </div>
    <div id="main-nav-mobile" class="header-sub header-inner">
        <table class="menu outer">
            <tr>
                
                    <td ><a  class="main-nav-link" href="/.">首页</a></td>
                
                    <td ><a  class="main-nav-link" href="/archives">时间轴</a></td>
                
                    <td ><a  class="main-nav-link" href="/categories">文章专题</a></td>
                
                    <td ><a  class="main-nav-link" href="/tags">标签云</a></td>
                
                    <td ><a  class="main-nav-link" href="/about">关于我</a></td>
                
                <td>
                    
    <div class="search-form">
        <input type="text" class="ins-search-input search-form-input" placeholder="搜索" />
    </div>

                </td>
            </tr>
        </table>
    </div>
</header>

        <div class="outer">
            
                

<aside id="profile">
    <div class="inner profile-inner">
        <div class="base-info profile-block">
            <img id="avatar" src="/css/images/avatar.png" />
            <h2 id="name">恒宇少年</h2>
            <h3 id="title">Java软件工程师 &amp; 程序猿</h3>
            <span id="location"><i class="fa fa-map-marker"></i>山东, 济南</span>
            <a id="follow" target="_blank" href="https://www.jianshu.com/u/092df3f77bca">关注我</a>
        </div>
        <div class="article-info profile-block">
            <div class="article-info-block">
                43
                <span>文章</span>
            </div>
            <div class="article-info-block">
                2
                <span>标签</span>
            </div>
        </div>
        
        <div class="profile-block social-links">
            <table>
                <tr>
                    
                    
                    <td>
                        <a href="http://github.com/ppoffice/hexo-theme-icarus" target="_blank" title="github" class=tooltip>
                            <i class="fa fa-github"></i>
                        </a>
                    </td>
                    
                    <td>
                        <a href="/" target="_blank" title="twitter" class=tooltip>
                            <i class="fa fa-twitter"></i>
                        </a>
                    </td>
                    
                    <td>
                        <a href="/" target="_blank" title="facebook" class=tooltip>
                            <i class="fa fa-facebook"></i>
                        </a>
                    </td>
                    
                    <td>
                        <a href="/" target="_blank" title="dribbble" class=tooltip>
                            <i class="fa fa-dribbble"></i>
                        </a>
                    </td>
                    
                    <td>
                        <a href="/" target="_blank" title="rss" class=tooltip>
                            <i class="fa fa-rss"></i>
                        </a>
                    </td>
                    
                </tr>
            </table>
        </div>
        
    </div>
</aside>

            
            <section id="main"><article id="post-querydsl-chapter-5" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 class="article-title" itemprop="name">
            第五章：使用QueryDSL与SpringDataJPA实现查询返回自定义对象
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/querydsl-chapter-5/">
            <time datetime="2017-07-10T16:00:00.000Z" itemprop="datePublished">2017-07-11</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/QueryDSL-核心技术/">QueryDSL 核心技术</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link" href="/tags/QueryDSL/">QueryDSL</a>, <a class="tag-link" href="/tags/SpringBoot/">SpringBoot</a>
    </div>

                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p>在我们实际项目开发中，往往会遇到一种多表关联查询并且仅需要返回多表内的几个字段最后组合成一个集合或者实体。这种情况在传统的查询中我们无法控制查询的字段，只能全部查询出后再做出分离，这种也是我们最不愿意看到的处理方式，这种方式会产生繁琐、复杂、效率低、代码阅读性差等等问题。QueryDSL为我们提供了一个返回自定义对象的工具类型，而Java8新特性Collection中stream方法也能够完成返回自定义对象的逻辑，下面我们就来看下这两种方式如何编写？<br><a id="more"></a></p>
<h1 id="本章目标"><a href="#本章目标" class="headerlink" title="本章目标"></a>本章目标</h1><p>基于SpringBoot平台完成SpringDataJPA与QueryDSL整合查询返回自定义对象的两种方式。</p>
<h1 id="构建项目"><a href="#构建项目" class="headerlink" title="构建项目"></a>构建项目</h1><p>我们先来使用idea工具创建一个SpringBoot项目，预先添加相对应的依赖，pom.xml配置文件内容如下所示：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="line">&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span><br><span class="line">    xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;</span><br><span class="line">    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;</span><br><span class="line"></span><br><span class="line">    &lt;groupId&gt;com.yuqiyu.querydsl.sample&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;chapter5&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;</span><br><span class="line">    &lt;packaging&gt;war&lt;/packaging&gt;</span><br><span class="line"></span><br><span class="line">    &lt;name&gt;chapter5&lt;/name&gt;</span><br><span class="line">    &lt;description&gt;Demo project for Spring Boot&lt;/description&gt;</span><br><span class="line"></span><br><span class="line">    &lt;parent&gt;</span><br><span class="line">        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">        &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;</span><br><span class="line">        &lt;version&gt;1.5.4.RELEASE&lt;/version&gt;</span><br><span class="line">        &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;</span><br><span class="line">    &lt;/parent&gt;</span><br><span class="line"></span><br><span class="line">    &lt;properties&gt;</span><br><span class="line">        &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;</span><br><span class="line">        &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;</span><br><span class="line">        &lt;java.version&gt;1.8&lt;/java.version&gt;</span><br><span class="line">    &lt;/properties&gt;</span><br><span class="line"></span><br><span class="line">    &lt;dependencies&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;mysql&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;</span><br><span class="line">            &lt;scope&gt;runtime&lt;/scope&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">        &lt;!--阿里巴巴数据库连接池，专为监控而生 --&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;com.alibaba&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;druid&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;1.0.26&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">        &lt;!-- 阿里巴巴fastjson，解析json视图 --&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;com.alibaba&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;fastjson&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;1.2.15&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;</span><br><span class="line">            &lt;!--&lt;scope&gt;provided&lt;/scope&gt;--&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;</span><br><span class="line">            &lt;scope&gt;test&lt;/scope&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">        &lt;!--queryDSL--&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;com.querydsl&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;querydsl-jpa&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;$&#123;querydsl.version&#125;&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;com.querydsl&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;querydsl-apt&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;$&#123;querydsl.version&#125;&lt;/version&gt;</span><br><span class="line">            &lt;scope&gt;provided&lt;/scope&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;lombok&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;1.16.16&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;javax.inject&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;javax.inject&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;1&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line">    &lt;/dependencies&gt;</span><br><span class="line"></span><br><span class="line">    &lt;build&gt;</span><br><span class="line">        &lt;plugins&gt;</span><br><span class="line">            &lt;plugin&gt;</span><br><span class="line">                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">                &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;</span><br><span class="line">            &lt;/plugin&gt;</span><br><span class="line">            &lt;!--添加QueryDSL插件支持--&gt;</span><br><span class="line">            &lt;plugin&gt;</span><br><span class="line">                &lt;groupId&gt;com.mysema.maven&lt;/groupId&gt;</span><br><span class="line">                &lt;artifactId&gt;apt-maven-plugin&lt;/artifactId&gt;</span><br><span class="line">                &lt;version&gt;1.1.3&lt;/version&gt;</span><br><span class="line">                &lt;executions&gt;</span><br><span class="line">                    &lt;execution&gt;</span><br><span class="line">                        &lt;goals&gt;</span><br><span class="line">                            &lt;goal&gt;process&lt;/goal&gt;</span><br><span class="line">                        &lt;/goals&gt;</span><br><span class="line">                        &lt;configuration&gt;</span><br><span class="line">                            &lt;outputDirectory&gt;target/generated-sources/java&lt;/outputDirectory&gt;</span><br><span class="line">                            &lt;processor&gt;com.querydsl.apt.jpa.JPAAnnotationProcessor&lt;/processor&gt;</span><br><span class="line">                        &lt;/configuration&gt;</span><br><span class="line">                    &lt;/execution&gt;</span><br><span class="line">                &lt;/executions&gt;</span><br><span class="line">            &lt;/plugin&gt;</span><br><span class="line">        &lt;/plugins&gt;</span><br><span class="line">    &lt;/build&gt;</span><br><span class="line">&lt;/project&gt;</span><br></pre></td></tr></table></figure></p>
<p>上面内的QueryDSL这里就不多做讲解了，如有疑问请查看<a href="http://www.jianshu.com/p/a22447c0897c" target="_blank" rel="noopener">第一章：Maven环境下如何配置QueryDSL环境</a>。<br>下面我们需要创建两张表来完成本章的内容。</p>
<h1 id="创建表结构"><a href="#创建表结构" class="headerlink" title="创建表结构"></a>创建表结构</h1><p>跟上一章一样，我们还是使用商品信息表、商品类型表来完成编码。</p>
<h4 id="商品信息表"><a href="#商品信息表" class="headerlink" title="商品信息表"></a>商品信息表</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">-- ----------------------------</span><br><span class="line">-- Table structure for good_infos</span><br><span class="line">-- ----------------------------</span><br><span class="line">DROP TABLE IF EXISTS `good_infos`;</span><br><span class="line">CREATE TABLE `good_infos` (</span><br><span class="line">  `tg_id` int(11) NOT NULL AUTO_INCREMENT COMMENT &apos;主键自增&apos;,</span><br><span class="line">  `tg_title` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT &apos;商品标题&apos;,</span><br><span class="line">  `tg_price` decimal(8,2) DEFAULT NULL COMMENT &apos;商品单价&apos;,</span><br><span class="line">  `tg_unit` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT &apos;单位&apos;,</span><br><span class="line">  `tg_order` varchar(255) DEFAULT NULL COMMENT &apos;排序&apos;,</span><br><span class="line">  `tg_type_id` int(11) DEFAULT NULL COMMENT &apos;类型外键编号&apos;,</span><br><span class="line">  PRIMARY KEY (`tg_id`),</span><br><span class="line">  KEY `tg_type_id` (`tg_type_id`)</span><br><span class="line">) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;</span><br><span class="line"></span><br><span class="line">-- ----------------------------</span><br><span class="line">-- Records of good_infos</span><br><span class="line">-- ----------------------------</span><br><span class="line">INSERT INTO `good_infos` VALUES (&apos;1&apos;, &apos;金针菇&apos;, &apos;5.50&apos;, &apos;斤&apos;, &apos;1&apos;, &apos;3&apos;);</span><br><span class="line">INSERT INTO `good_infos` VALUES (&apos;2&apos;, &apos;油菜&apos;, &apos;12.60&apos;, &apos;斤&apos;, &apos;2&apos;, &apos;1&apos;);</span><br></pre></td></tr></table></figure>
<h4 id="商品类型信息表"><a href="#商品类型信息表" class="headerlink" title="商品类型信息表"></a>商品类型信息表</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">-- ----------------------------</span><br><span class="line">-- Table structure for good_types</span><br><span class="line">-- ----------------------------</span><br><span class="line">DROP TABLE IF EXISTS `good_types`;</span><br><span class="line">CREATE TABLE `good_types` (</span><br><span class="line">  `tgt_id` int(11) NOT NULL AUTO_INCREMENT COMMENT &apos;主键自增&apos;,</span><br><span class="line">  `tgt_name` varchar(30) CHARACTER SET utf8 DEFAULT NULL COMMENT &apos;类型名称&apos;,</span><br><span class="line">  `tgt_is_show` char(1) DEFAULT NULL COMMENT &apos;是否显示&apos;,</span><br><span class="line">  `tgt_order` int(2) DEFAULT NULL COMMENT &apos;类型排序&apos;,</span><br><span class="line">  PRIMARY KEY (`tgt_id`)</span><br><span class="line">) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;</span><br><span class="line"></span><br><span class="line">-- ----------------------------</span><br><span class="line">-- Records of good_types</span><br><span class="line">-- ----------------------------</span><br><span class="line">INSERT INTO `good_types` VALUES (&apos;1&apos;, &apos;绿色蔬菜&apos;, &apos;1&apos;, &apos;1&apos;);</span><br><span class="line">INSERT INTO `good_types` VALUES (&apos;2&apos;, &apos;根茎类&apos;, &apos;1&apos;, &apos;2&apos;);</span><br><span class="line">INSERT INTO `good_types` VALUES (&apos;3&apos;, &apos;菌类&apos;, &apos;1&apos;, &apos;3&apos;);</span><br></pre></td></tr></table></figure>
<h1 id="创建实体"><a href="#创建实体" class="headerlink" title="创建实体"></a>创建实体</h1><p>我们对应表结构创建实体并且添加对应的SpringDataJPA注解。</p>
<h4 id="商品实体"><a href="#商品实体" class="headerlink" title="商品实体"></a>商品实体</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">package com.yuqiyu.querydsl.sample.chapter5.bean;</span><br><span class="line"></span><br><span class="line">import lombok.Data;</span><br><span class="line"></span><br><span class="line">import javax.persistence.*;</span><br><span class="line">import java.io.Serializable;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * 商品基本信息实体</span><br><span class="line"> * ========================</span><br><span class="line"> * Created with IntelliJ IDEA.</span><br><span class="line"> * User：恒宇少年</span><br><span class="line"> * Date：2017/7/10</span><br><span class="line"> * Time：22:39</span><br><span class="line"> * 码云：http://git.oschina.net/jnyqy</span><br><span class="line"> * ========================</span><br><span class="line"> */</span><br><span class="line">@Entity</span><br><span class="line">@Table(name = &quot;good_infos&quot;)</span><br><span class="line">@Data</span><br><span class="line">public class GoodInfoBean</span><br><span class="line">    implements Serializable</span><br><span class="line">&#123;</span><br><span class="line">    //主键</span><br><span class="line">    @Id</span><br><span class="line">    @Column(name = &quot;tg_id&quot;)</span><br><span class="line">    @GeneratedValue</span><br><span class="line">    private Long id;</span><br><span class="line">    //标题</span><br><span class="line">    @Column(name = &quot;tg_title&quot;)</span><br><span class="line">    private String title;</span><br><span class="line">    //价格</span><br><span class="line">    @Column(name = &quot;tg_price&quot;)</span><br><span class="line">    private double price;</span><br><span class="line">    //单位</span><br><span class="line">    @Column(name = &quot;tg_unit&quot;)</span><br><span class="line">    private String unit;</span><br><span class="line">    //排序</span><br><span class="line">    @Column(name = &quot;tg_order&quot;)</span><br><span class="line">    private int order;</span><br><span class="line">    //类型编号</span><br><span class="line">    @Column(name = &quot;tg_type_id&quot;)</span><br><span class="line">    private Long typeId;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="商品类型实体"><a href="#商品类型实体" class="headerlink" title="商品类型实体"></a>商品类型实体</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">package com.yuqiyu.querydsl.sample.chapter5.bean;</span><br><span class="line"></span><br><span class="line">import lombok.Data;</span><br><span class="line"></span><br><span class="line">import javax.persistence.*;</span><br><span class="line">import java.io.Serializable;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * 商品类别实体</span><br><span class="line"> * ========================</span><br><span class="line"> * Created with IntelliJ IDEA.</span><br><span class="line"> * User：恒宇少年</span><br><span class="line"> * Date：2017/7/10</span><br><span class="line"> * Time：22:39</span><br><span class="line"> * 码云：http://git.oschina.net/jnyqy</span><br><span class="line"> * ========================</span><br><span class="line"> */</span><br><span class="line">@Entity</span><br><span class="line">@Table(name = &quot;good_types&quot;)</span><br><span class="line">@Data</span><br><span class="line">public class GoodTypeBean</span><br><span class="line">    implements Serializable</span><br><span class="line">&#123;</span><br><span class="line">    //类型编号</span><br><span class="line">    @Id</span><br><span class="line">    @GeneratedValue</span><br><span class="line">    @Column(name = &quot;tgt_id&quot;)</span><br><span class="line">    private Long id;</span><br><span class="line">    //类型名称</span><br><span class="line">    @Column(name = &quot;tgt_name&quot;)</span><br><span class="line">    private String name;</span><br><span class="line">    //是否显示</span><br><span class="line">    @Column(name = &quot;tgt_is_show&quot;)</span><br><span class="line">    private int isShow;</span><br><span class="line">    //排序</span><br><span class="line">    @Column(name = &quot;tgt_order&quot;)</span><br><span class="line">    private int order;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>上面实体内的注解@Entity标识该实体被SpringDataJPA所管理，@Table标识该实体对应的数据库内的表信息，@Data该注解则是lombok内的合并注解，根据idea工具的插件自动添加getter/setter、toString、全参构造函数等。</p>
<h1 id="创建DTO"><a href="#创建DTO" class="headerlink" title="创建DTO"></a>创建DTO</h1><p>我们创建一个查询返回的自定义对象，对象内的字段包含了商品实体、商品类型实体内的部分内容，DTO代码如下所示：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">package com.yuqiyu.querydsl.sample.chapter5.dto;</span><br><span class="line"></span><br><span class="line">import lombok.Data;</span><br><span class="line"></span><br><span class="line">import java.io.Serializable;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * 商品dto</span><br><span class="line"> * ========================</span><br><span class="line"> * Created with IntelliJ IDEA.</span><br><span class="line"> * User：恒宇少年</span><br><span class="line"> * Date：2017/7/10</span><br><span class="line"> * Time：22:39</span><br><span class="line"> * 码云：http://git.oschina.net/jnyqy</span><br><span class="line"> * ========================</span><br><span class="line"> */</span><br><span class="line">@Data</span><br><span class="line">public class GoodDTO</span><br><span class="line">    implements Serializable</span><br><span class="line">&#123;</span><br><span class="line">    //主键</span><br><span class="line">    private Long id;</span><br><span class="line">    //标题</span><br><span class="line">    private String title;</span><br><span class="line">    //单位</span><br><span class="line">    private String unit;</span><br><span class="line">    //价格</span><br><span class="line">    private double price;</span><br><span class="line">    //类型名称</span><br><span class="line">    private String typeName;</span><br><span class="line">    //类型编号</span><br><span class="line">    private Long typeId;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>要注意我们的自定义返回的对象仅仅只是一个实体，并不对应数据库内的表，所以这里不需要配置@Entity、@Table等JPA注解，仅把@Data注解配置上就可以了，接下来我们编译下项目让QueryDSL插件自动生成查询实体。</p>
<h1 id="生成查询实体"><a href="#生成查询实体" class="headerlink" title="生成查询实体"></a>生成查询实体</h1><p>idea工具为maven project自动添加了对应的功能，我们打开右侧的Maven Projects，如下图1所示：</p>
<p><img src="http://upload-images.jianshu.io/upload_images/4461954-8c9862af270a9d02.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图1"><br>我们双击compile命令执行，执行完成后会在我们pom.xml配置文件内配置生成目录内生成对应实体的QueryDSL查询实体。生成的查询实体如下图2所示：</p>
<p><img src="http://upload-images.jianshu.io/upload_images/4461954-24a7bc6f80b6b210.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图2"></p>
<blockquote>
<p>QueryDSL配置JPA插件仅会根据@Entity进行生成查询实体</p>
</blockquote>
<p>#创建控制器<br>我们来创建一个测试的控制器读取商品表内的所有商品，在编写具体的查询方法之前我们需要实例化EntityManager对象以及JPAQueryFactory对象，并且通过实例化控制器时就去实例化JPAQueryFactory对象。控制器代码如下所示：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">package com.yuqiyu.querydsl.sample.chapter5.controller;</span><br><span class="line"></span><br><span class="line">import com.querydsl.core.types.Projections;</span><br><span class="line">import com.querydsl.jpa.impl.JPAQueryFactory;</span><br><span class="line">import com.yuqiyu.querydsl.sample.chapter5.bean.QGoodInfoBean;</span><br><span class="line">import com.yuqiyu.querydsl.sample.chapter5.bean.QGoodTypeBean;</span><br><span class="line">import com.yuqiyu.querydsl.sample.chapter5.dto.GoodDTO;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.web.bind.annotation.RequestMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.RestController;</span><br><span class="line"></span><br><span class="line">import javax.annotation.PostConstruct;</span><br><span class="line">import javax.persistence.EntityManager;</span><br><span class="line">import java.util.List;</span><br><span class="line">import java.util.stream.Collectors;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * 多表查询返回商品dto控制器</span><br><span class="line"> * ========================</span><br><span class="line"> * Created with IntelliJ IDEA.</span><br><span class="line"> * User：恒宇少年</span><br><span class="line"> * Date：2017/7/10</span><br><span class="line"> * Time：23:04</span><br><span class="line"> * 码云：http://git.oschina.net/jnyqy</span><br><span class="line"> * ========================</span><br><span class="line"> */</span><br><span class="line">@RestController</span><br><span class="line">public class GoodController</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line">    //实体管理</span><br><span class="line">    @Autowired</span><br><span class="line">    private EntityManager entityManager;</span><br><span class="line"></span><br><span class="line">    //查询工厂</span><br><span class="line">    private JPAQueryFactory queryFactory;</span><br><span class="line"></span><br><span class="line">    //初始化查询工厂</span><br><span class="line">    @PostConstruct</span><br><span class="line">    public void init()</span><br><span class="line">    &#123;</span><br><span class="line">        queryFactory = new JPAQueryFactory(entityManager);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>可以看到我们配置的是一个@RestController该控制器返回的数据都是Json字符串,这也是RestController所遵循的规则。</p>
<h2 id="QueryDSL-amp-Projections"><a href="#QueryDSL-amp-Projections" class="headerlink" title="QueryDSL &amp; Projections"></a>QueryDSL &amp; Projections</h2><p>下面我们开始编写完全基于QueryDSL形式的返回自定义对象方法，代码如下所示：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">    * 根据QueryDSL查询</span><br><span class="line">    * @return</span><br><span class="line">    */</span><br><span class="line">   @RequestMapping(value = &quot;/selectWithQueryDSL&quot;)</span><br><span class="line">   public List&lt;GoodDTO&gt; selectWithQueryDSL()</span><br><span class="line">   &#123;</span><br><span class="line">       //商品基本信息</span><br><span class="line">       QGoodInfoBean _Q_good = QGoodInfoBean.goodInfoBean;</span><br><span class="line">       //商品类型</span><br><span class="line">       QGoodTypeBean _Q_good_type = QGoodTypeBean.goodTypeBean;</span><br><span class="line"></span><br><span class="line">       return queryFactory</span><br><span class="line">               .select(</span><br><span class="line">                       Projections.bean(</span><br><span class="line">                               GoodDTO.class,//返回自定义实体的类型</span><br><span class="line">                               _Q_good.id,</span><br><span class="line">                               _Q_good.price,</span><br><span class="line">                               _Q_good.title,</span><br><span class="line">                               _Q_good.unit,</span><br><span class="line">                               _Q_good_type.name.as(&quot;typeName&quot;),//使用别名对应dto内的typeName</span><br><span class="line">                               _Q_good_type.id.as(&quot;typeId&quot;)//使用别名对应dto内的typeId</span><br><span class="line">                        )</span><br><span class="line">               )</span><br><span class="line">               .from(_Q_good,_Q_good_type)//构建两表笛卡尔集</span><br><span class="line">               .where(_Q_good.typeId.eq(_Q_good_type.id))//关联两表</span><br><span class="line">               .orderBy(_Q_good.order.desc())//倒序</span><br><span class="line">               .fetch();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure></p>
<p>我们可以看到上面selectWithQueryDSL()查询方法，里面出现了一个新的类型Projections，这个类型是QueryDSL内置针对处理自定义返回结果集的解决方案，里面包含了构造函数、实体、字段等处理方法，我们今天主要讲解下实体。</p>
<p>JPAQueryFactory工厂select方法可以将Projections方法返回的QBean作为参数，我们通过Projections的bean方法来构建返回的结果集映射到实体内，有点像Mybatis内的ResultMap的形式，不过内部处理机制肯定是有着巨大差别的！bean方法第一个参数需要传递一个实体的泛型类型作为返回集合内的单个对象类型，如果QueryDSL查询实体内的字段与DTO实体的字段名字不一样时，我们就可以采用as方法来处理，为查询的结果集指定的字段添加别名，这样就会自动映射到DTO实体内。</p>
<h2 id="运行测试"><a href="#运行测试" class="headerlink" title="运行测试"></a>运行测试</h2><p>下面我们来运行下项目，访问地址：<a href="http://127.0.0.1:8080/selectWithQueryDSL" target="_blank" rel="noopener">http://127.0.0.1:8080/selectWithQueryDSL</a>查看界面输出的效果如下代码块所示：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line">    &#123;</span><br><span class="line">        &quot;id&quot;: 2,</span><br><span class="line">        &quot;title&quot;: &quot;油菜&quot;,</span><br><span class="line">        &quot;unit&quot;: &quot;斤&quot;,</span><br><span class="line">        &quot;price&quot;: 12.6,</span><br><span class="line">        &quot;typeName&quot;: &quot;绿色蔬菜&quot;,</span><br><span class="line">        &quot;typeId&quot;: 1</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        &quot;id&quot;: 1,</span><br><span class="line">        &quot;title&quot;: &quot;金针菇&quot;,</span><br><span class="line">        &quot;unit&quot;: &quot;斤&quot;,</span><br><span class="line">        &quot;price&quot;: 5.5,</span><br><span class="line">        &quot;typeName&quot;: &quot;菌类&quot;,</span><br><span class="line">        &quot;typeId&quot;: 3</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure></p>
<p>我们可以看到输出的Json数组字符串就是我们DTO内的所有字段反序列后的效果，DTO实体内对应的typeName、typeId都已经查询出并且赋值。<br>下面我们来查看控制台输出自动生成的SQL，如下代码块所示：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">Hibernate: </span><br><span class="line">    select</span><br><span class="line">        goodinfobe0_.tg_id as col_0_0_,</span><br><span class="line">        goodinfobe0_.tg_price as col_1_0_,</span><br><span class="line">        goodinfobe0_.tg_title as col_2_0_,</span><br><span class="line">        goodinfobe0_.tg_unit as col_3_0_,</span><br><span class="line">        goodtypebe1_.tgt_name as col_4_0_,</span><br><span class="line">        goodtypebe1_.tgt_id as col_5_0_ </span><br><span class="line">    from</span><br><span class="line">        good_infos goodinfobe0_ cross </span><br><span class="line">    join</span><br><span class="line">        good_types goodtypebe1_ </span><br><span class="line">    where</span><br><span class="line">        goodinfobe0_.tg_type_id=goodtypebe1_.tgt_id </span><br><span class="line">    order by</span><br><span class="line">        goodinfobe0_.tg_order desc</span><br></pre></td></tr></table></figure></p>
<p>生成的SQL是cross join形式关联查询，关联 形式通过where goodinfobe0_.tg_type<em>id=goodtypebe1</em>.tgt<em>id  代替了on goodinfobe0</em>.tg_type<em>id=goodtypebe1</em>.tgt_id，最终查询结果集返回数据这两种方式一致。</p>
<h2 id="QueryDSL-amp-Collection"><a href="#QueryDSL-amp-Collection" class="headerlink" title="QueryDSL &amp; Collection"></a>QueryDSL &amp; Collection</h2><p>下面我们采用java8新特性返回自定义结果集，我们查询仍然采用QueryDSL形式，方法代码如下所示：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">    * 使用java8新特性Collection内stream方法转换dto</span><br><span class="line">    * @return</span><br><span class="line">    */</span><br><span class="line">   @RequestMapping(value = &quot;/selectWithStream&quot;)</span><br><span class="line">   public List&lt;GoodDTO&gt; selectWithStream()</span><br><span class="line">   &#123;</span><br><span class="line">       //商品基本信息</span><br><span class="line">       QGoodInfoBean _Q_good = QGoodInfoBean.goodInfoBean;</span><br><span class="line">       //商品类型</span><br><span class="line">       QGoodTypeBean _Q_good_type = QGoodTypeBean.goodTypeBean;</span><br><span class="line">       return queryFactory</span><br><span class="line">               .select(</span><br><span class="line">                       _Q_good.id,</span><br><span class="line">                       _Q_good.price,</span><br><span class="line">                       _Q_good.title,</span><br><span class="line">                       _Q_good.unit,</span><br><span class="line">                       _Q_good_type.name,</span><br><span class="line">                       _Q_good_type.id</span><br><span class="line">               )</span><br><span class="line">               .from(_Q_good,_Q_good_type)//构建两表笛卡尔集</span><br><span class="line">               .where(_Q_good.typeId.eq(_Q_good_type.id))//关联两表</span><br><span class="line">               .orderBy(_Q_good.order.desc())//倒序</span><br><span class="line">               .fetch()</span><br><span class="line">               .stream()</span><br><span class="line">               //转换集合内的数据</span><br><span class="line">               .map(tuple -&gt; &#123;</span><br><span class="line">                   //创建商品dto</span><br><span class="line">                   GoodDTO dto = new GoodDTO();</span><br><span class="line">                   //设置商品编号</span><br><span class="line">                   dto.setId(tuple.get(_Q_good.id));</span><br><span class="line">                   //设置商品价格</span><br><span class="line">                   dto.setPrice(tuple.get(_Q_good.price));</span><br><span class="line">                   //设置商品标题</span><br><span class="line">                   dto.setTitle(tuple.get(_Q_good.title));</span><br><span class="line">                   //设置单位</span><br><span class="line">                   dto.setUnit(tuple.get(_Q_good.unit));</span><br><span class="line">                   //设置类型编号</span><br><span class="line">                   dto.setTypeId(tuple.get(_Q_good_type.id));</span><br><span class="line">                   //设置类型名称</span><br><span class="line">                   dto.setTypeName(tuple.get(_Q_good_type.name));</span><br><span class="line">                   //返回本次构建的dto</span><br><span class="line">                   return dto;</span><br><span class="line">               &#125;)</span><br><span class="line">               //返回集合并且转换为List&lt;GoodDTO&gt;</span><br><span class="line">               .collect(Collectors.toList());</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure></p>
<p>从方法开始到fetch()结束完全跟QueryDSL没有任何区别，采用了最原始的方式进行返回结果集，但是从fetch()获取到结果集后我们处理的方式就有所改变了，fetch()方法返回的类型是泛型List（List<t>），List继承了Collection，完全存在使用Collection内非私有方法的权限，通过调用stream方法可以将集合转换成Stream<e>泛型对象，该对象的map方法可以操作集合内单个对象的转换，具体的转换代码可以根据业务逻辑进行编写。<br>在map方法内有个lambda表达式参数tuple，我们通过tuple对象get方法就可以获取对应select方法内的查询字段。</e></t></p>
<blockquote>
<p>tuple只能获取select内存在的字段，如果select内为一个实体对象，tuple无法获取指定字段的值。</p>
</blockquote>
<h2 id="运行测试-1"><a href="#运行测试-1" class="headerlink" title="运行测试"></a>运行测试</h2><p>下面我们重启下项目，访问地址：<a href="127.0.0.1:8080/selectWithStream" target="_blank" rel="noopener">127.0.0.1:8080/selectWithStream</a>，界面输出的内容如下代码块所示：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line">    &#123;</span><br><span class="line">        &quot;id&quot;: 2,</span><br><span class="line">        &quot;title&quot;: &quot;油菜&quot;,</span><br><span class="line">        &quot;unit&quot;: &quot;斤&quot;,</span><br><span class="line">        &quot;price&quot;: 12.6,</span><br><span class="line">        &quot;typeName&quot;: &quot;绿色蔬菜&quot;,</span><br><span class="line">        &quot;typeId&quot;: 1</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        &quot;id&quot;: 1,</span><br><span class="line">        &quot;title&quot;: &quot;金针菇&quot;,</span><br><span class="line">        &quot;unit&quot;: &quot;斤&quot;,</span><br><span class="line">        &quot;price&quot;: 5.5,</span><br><span class="line">        &quot;typeName&quot;: &quot;菌类&quot;,</span><br><span class="line">        &quot;typeId&quot;: 3</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure></p>
<p>可以看到返回的数据跟上面方法是一致的，当然你们也能猜到自动生成的SQL也是一样的，这里SQL就不做多解释了。</p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>以上内容就是本章的全部内容，本章讲解的两种方法都是基于QueryDSL进行查询只不过一种采用QueryDSL为我们提供的形式封装自定义对象，而另外一种则是采用java8特性来完成的，Projections与Stream还有很多其他的方法，有兴趣的小伙伴可以自行GitHub去查看。</p>
<p>QueryDSL官方文档：<a href="http://www.querydsl.com/static/querydsl/latest/reference/html/ch02.html" target="_blank" rel="noopener">http://www.querydsl.com/static/querydsl/latest/reference/html/ch02.html</a><br>本章代码已经上传码云：<br>SpringBoot配套源码地址：<a href="https://gitee.com/hengboy/spring-boot-chapter" target="_blank" rel="noopener">https://gitee.com/hengboy/spring-boot-chapter</a><br>SpringCloud配套源码地址：<a href="https://gitee.com/hengboy/spring-cloud-chapter" target="_blank" rel="noopener">https://gitee.com/hengboy/spring-cloud-chapter</a><br>SpringBoot相关系列文章请访问：<a href="http://www.jianshu.com/p/9a08417e4e84" target="_blank" rel="noopener">目录：SpringBoot学习目录</a><br>QueryDSL相关系列文章请访问：<a href="http://www.jianshu.com/p/99a5ec5c3bd5" target="_blank" rel="noopener">QueryDSL通用查询框架学习目录</a><br>SpringDataJPA相关系列文章请访问：<a href="http://www.jianshu.com/p/615ed9c1fe84" target="_blank" rel="noopener">目录：SpringDataJPA学习目录</a><br>感谢阅读！<br>欢迎加入QQ技术交流群，共同进步。<br><img src="http://upload-images.jianshu.io/upload_images/4461954-f1d4cb64234b160a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="QQ技术交流群"></p>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    

        </footer>
    </div>
    
        
<nav id="article-nav">
    
        <a href="/querydsl-chapter-6/" id="article-nav-newer" class="article-nav-link-wrap">
            <strong class="article-nav-caption">上一篇</strong>
            <div class="article-nav-title">
                
                    第六章：使用QueryDSL的聚合函数
                
            </div>
        </a>
    
    
        <a href="/querydsl-chapter-4/" id="article-nav-older" class="article-nav-link-wrap">
            <strong class="article-nav-caption">下一篇</strong>
            <div class="article-nav-title">第四章：使用QueryDSL与SpringDataJPA实现多表关联查询</div>
        </a>
    
</nav>


    
</article>


    
    

</section>
            
			
				
<aside id="sidebar">
   
        
    <div class="widget-wrap">
        <h3 class="widget-title">最新文章</h3>
        <div class="widget">
            <ul id="recent-post" class="no-thumbnail">
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"><a class="article-category-link" href="/categories/SpringBoot-核心技术/">SpringBoot 核心技术</a></p>
                            <p class="item-title"><a href="/spring-boot-chapter-52/" class="title">第五十二章：基于SpringBoot2使用Rest访问MongoDB数据</a></p>
                            <p class="item-date"><time datetime="2018-04-21T16:00:00.000Z" itemprop="datePublished">2018-04-22</time></p>
                        </div>
                    </li>
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"><a class="article-category-link" href="/categories/SpringBoot-核心技术/">SpringBoot 核心技术</a></p>
                            <p class="item-title"><a href="/spring-boot-chapter-51/" class="title">第五十一章：基于SpringBoot2 &amp; MongoDB完成自动化集成</a></p>
                            <p class="item-date"><time datetime="2018-04-15T16:00:00.000Z" itemprop="datePublished">2018-04-16</time></p>
                        </div>
                    </li>
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"><a class="article-category-link" href="/categories/SpringBoot-核心技术/">SpringBoot 核心技术</a></p>
                            <p class="item-title"><a href="/spring-boot-chapter-50/" class="title">第五十章：SpringBoot2.0新特性 - 岂止至今最简单redis缓存集成</a></p>
                            <p class="item-date"><time datetime="2018-04-14T16:00:00.000Z" itemprop="datePublished">2018-04-15</time></p>
                        </div>
                    </li>
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"><a class="article-category-link" href="/categories/SpringBoot-核心技术/">SpringBoot 核心技术</a></p>
                            <p class="item-title"><a href="/spring-boot-chapter-49/" class="title">第四十九章：SpringBoot2.0新特性 - 你get到WebMvcConfigurer两种配置方式了吗？</a></p>
                            <p class="item-date"><time datetime="2018-03-16T16:00:00.000Z" itemprop="datePublished">2018-03-17</time></p>
                        </div>
                    </li>
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"><a class="article-category-link" href="/categories/SpringBoot-核心技术/">SpringBoot 核心技术</a></p>
                            <p class="item-title"><a href="/spring-boot-chapter-48/" class="title">第四十八章：SpringBoot2.0新特性 - RabbitMQ信任package设置</a></p>
                            <p class="item-date"><time datetime="2018-03-12T16:00:00.000Z" itemprop="datePublished">2018-03-13</time></p>
                        </div>
                    </li>
                
            </ul>
        </div>
    </div>

    
        
    <div class="widget-wrap">
        <h3 class="widget-title">分类</h3>
        <div class="widget">
            <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/QueryDSL-核心技术/">QueryDSL 核心技术</a><span class="category-list-count">7</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/SpringBoot-核心技术/">SpringBoot 核心技术</a><span class="category-list-count">36</span></li></ul>
        </div>
    </div>

    
        
    <div class="widget-wrap">
        <h3 class="widget-title">归档</h3>
        <div class="widget">
            <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/04/">四月 2018</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/03/">三月 2018</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/01/">一月 2018</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/12/">十二月 2017</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/11/">十一月 2017</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/10/">十月 2017</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/09/">九月 2017</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/08/">八月 2017</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/07/">七月 2017</a><span class="archive-list-count">9</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/06/">六月 2017</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/05/">五月 2017</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/04/">四月 2017</a><span class="archive-list-count">5</span></li></ul>
        </div>
    </div>

    
        
    <div class="widget-wrap">
        <h3 class="widget-title">标签</h3>
        <div class="widget">
            <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/QueryDSL/">QueryDSL</a><span class="tag-list-count">7</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/SpringBoot/">SpringBoot</a><span class="tag-list-count">43</span></li></ul>
        </div>
    </div>

    
        
    <div class="widget-wrap">
        <h3 class="widget-title">标签云</h3>
        <div class="widget tagcloud">
            <a href="/tags/QueryDSL/" style="font-size: 10px;">QueryDSL</a> <a href="/tags/SpringBoot/" style="font-size: 20px;">SpringBoot</a>
        </div>
    </div>

    
        
    <div class="widget-wrap widget-list">
        <h3 class="widget-title">链接</h3>
        <div class="widget">
            <ul>
                
                    <li>
     				<a href="http://hexo.io" target="_blank">Hexo</a>
					</li>
                
            </ul>
        </div>
    </div>


    
    <div id="toTop" class="fa fa-angle-up"></div>
</aside>

				
        </div>
        <!--引入不蒜子-->
<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<footer id="footer">
    <div class="outer">
        <div id="footer-info" class="inner">
            <span  id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
            &copy; 2017 - 2018 恒宇少年 - 版权所有<br>
        </div>
    </div>
</footer>

        


    
        <script src="/libs/lightgallery/js/lightgallery.min.js"></script>
        <script src="/libs/lightgallery/js/lg-thumbnail.min.js"></script>
        <script src="/libs/lightgallery/js/lg-pager.min.js"></script>
        <script src="/libs/lightgallery/js/lg-autoplay.min.js"></script>
        <script src="/libs/lightgallery/js/lg-fullscreen.min.js"></script>
        <script src="/libs/lightgallery/js/lg-zoom.min.js"></script>
        <script src="/libs/lightgallery/js/lg-hash.min.js"></script>
        <script src="/libs/lightgallery/js/lg-share.min.js"></script>
        <script src="/libs/lightgallery/js/lg-video.min.js"></script>
    
    
        <script src="/libs/justified-gallery/jquery.justifiedGallery.min.js"></script>
    
    



<!-- Custom Scripts -->
<script src="/js/main.js"></script>

    </div>
</body>
</html>